home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
pascal
/
err87_13.zip
/
ERROR87.DOC
< prev
next >
Wrap
Text File
|
1993-01-24
|
7KB
|
155 lines
ERROR87 1.3 - Turbo Pascal units to improve coprocessor error reports.
Copyright (c) 1990,1993, D.J. Murdoch. All rights reserved.
Portions of DECODE87.PAS copyright 1985,86, L. David Baldwin.
INTRODUCTION
Turbo Pascal doesn't handle floating point errors well. The number of
errors that are reported as run-time "Error 207" is large, and in some
versions the error address is miscalculated, so you don't have a clue
where to look for them. ERROR87 is a unit that attempts to address both
of these problems - it gives more informative error messages, and it
tries to improve on the calculation of the error address.
METHOD
The ERROR87 unit doesn't interface anything. When you use it, it
patches the loaded copy of the system library, and installs an exit
procedure that looks for run-time coprocessor errors. (It does the
patch in memory; it won't affect the copy of the library that's on
disk, or the executable file on disk.)
When an error occurs, transfer is passed to the ERROR87 exit
procedure. If the error was an "Invalid Floating Point Operation",
i.e. run-time error 207, ERROR87 springs into action. First, it saves
the state of the coprocessor in memory. (The patch to the system
library was to prevent it from clearing the coprocessor's registers
before ERROR87 could get a look at them.) Then, it dissects the
state record to try to work out the cause of the error.
The first part of the post-mortem is to decode the instruction, using
code based on L. David Baldwin's excellent UNINLINE disassembler.
It then looks at the coprocessor's record of which instruction caused
the error, to see if TP has given the wrong error address. (Note:
TP/BP 7.0 get the error address right, so no fix is necessary there.
See the note below, though.) Finally, it proceeds through tests of what
I think are the most likely causes of invalid operations:
- taking the square root of a negative
- dividing 0/0
- overflowing the stack by recursive calls, or very complicated
expressions
- operating on NaNs ("Not a Number"s), probably because variables
weren't properly initialized, or a library routine like ln() has
been passed a negative number
- underflowing the stack, by a bug in assembler or inline code
It prints a message describing the error, and passes control on to the
next exit procedure.
LIMITATIONS
ERROR87 adds several kilobytes to the size of the program, and writes
messages to the standard output device, so you would probably only
want to use it while debugging.
TP calculates the trunc() function in a funny way. ERROR87 will often
be unable to recognize the error if the truncation overflows.
The coprocessor doesn't know the code segment of an instruction, only
the linear address. (The emulator knows less; see below.) ERROR87
creates a segmented address from this in versions 5.5 and 6.0; TP/BP 7
automatically returns a correct normalized address, so ERROR87 doesn't
touch it. However, none of the IDE versions know how to deal with the
error address when the segment is wrong. If you have the TP/BP 7
command line compiler, you can use the "/F xxxx:yyyy" option to find the
error. In earlier versions, you'll have to generate a .MAP file, figure
out which segment the address is in, and manually adjust the value for
TP. For example, if the program dies with the messages
Operand is not a number!
Runtime error 207 at 0000:46E3.
and TP can't find location 0000:46E3, take a look at the link map:
Start Stop Length Name Class
00000H 0008CH 0008DH TEST CODE
00090H 00ABEH 00A2FH ERROR87 CODE
00AC0H 0135FH 008A0H DECODE87 CODE
01360H 04927H 035C8H SYSTEM CODE <--- it's in here!
04930H 073B9H 02A8AH DATA DATA
073C0H 0B3BFH 04000H STACK STACK
0B3C0H 0B3C0H 00000H HEAP HEAP
From this map it's clear that one of the system routines had the
error, and there's not much you can do to find it. (This example
tried to calculate ln(-1).) If it had turned out to be in one of your
units, you could ask the compiler to find it by looking for the
address 0136:3383, i.e. (start div $10):(reported address - start).
The coprocessor emulator keeps no record of the bad instruction at all.
When run under an emulator, Error87 tries to find the instruction based
on the error address passed to it, but is not always successful.
I've attempted to add protected mode (DPMI) support for BP 7, but it
doesn't seem at all reliable. I don't know if this is caused by bugs
in BP or in Error87. Under Desqview it's even worse.
CONTENTS OF PACKAGE
In this package, you should find the following files:
ERROR87.DOC - this file
ERROR87.PAS - source code to the error handling unit
DECODE87.PAS - source code used to decode the instructions
DV87.ZIP - a little TSR to fix a bug in Desqview 2.26 that
crashes windows on coprocessor errors
NMI.ZIP - a little program to turn on NMI handling on XT clones,
so that they don't crash on coprocessor errors
REGISTRATION
ERROR87 is shareware. That means you can try it out for free, but if
you find that it helps you and you want to keep it, you must register.
Registration is only $10; send a cheque or money order for that amount
in Canadian or U.S. funds to
D.J. Murdoch
337 Willingdon Ave.
Kingston, Ontario, Canada,
K7L 4J7.
I'll answer technical questions from registered users, if they're
mailed to me at the above address, or by email to me at
dmurdoch@mast.queensu.ca on Internet
DJ Murdoch at node 1:249/99.5 on Fidonet
71631,122 on Compuserve
I'd like bug reports from you even if you don't register.
The unit DECODE87 is closely based on L. David Baldwin's UNINLINE
program. I release my contributions to it to the public domain, but
the actual decoding remains under his copyright. He has released it
for free non-commercial use.
RELEASE HISTORY
1.3 - January 1993 - Updated to work with TP/BP 7, including protected mode.
Improved the emulator handling marginally.
1.2 - February 1991 - Added check for emulator and warning message. The
emulator in TP 6.0 (and possibly 5.5) doesn't
properly emulate all of the coprocessor registers,
so Error87 messages will probably be wrong.
1.1 - August 1990 - added detection of trunc() and round() overflows
that I forgot in 1.0
1.0 - August 1990 - Initial release